package com.huazai.rabbitmq.controller;

import com.huazai.rabbitmq.config.exchange.RabbitDirectConfig;
import com.huazai.rabbitmq.config.exchange.RabbitTopicConfig;
import com.rabbitmq.client.Channel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.IOException;

/**
 *  参考地址：https://blog.csdn.net/AhangA/article/details/121641034
 *
 * @author 华仔
 * @date 2024/11/11
 */
@Slf4j
@Api(value = "TopicExchangeTestController", tags = "Topic类型（拓展匹配发送）测试")
@RestController
@RequestMapping(value = "/topic")
public class TopicExchangeTestController {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @RequestMapping(value = "/sendXin", method = RequestMethod.POST)
    @ApiOperation(value = "向*.two.*发信息", notes = "binding key中可以存在两种特殊字符 \" * \" 与 \" # \" ，用于做模糊匹配，其中“*”用于匹配一个单词，“#”用于匹配多个单词（可以是零个）")
    public String sendXin(@ApiParam(name = "topicRoutingkey", value = "主题路由key", required = true, defaultValue = "one.Tow.one") @RequestParam String topicRoutingkey) {
        rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPIC_EX, topicRoutingkey, "one-msg");
        return "成功";
    }

    @RequestMapping(value = "/sendJing", method = RequestMethod.POST)
    @ApiOperation(value = "向#发信息",notes = "binding key中可以存在两种特殊字符 \" * \" 与 \" # \" ，用于做模糊匹配，其中“*”用于匹配一个单词，“#”用于匹配多个单词（可以是零个）")
    public String sendJing(@ApiParam(name = "topicRoutingkey", value = "主题路由key", required = true, defaultValue = "one.one.one") @RequestParam String topicRoutingkey) {
        rabbitTemplate.convertAndSend(RabbitTopicConfig.TOPIC_EX, topicRoutingkey, "one-two");
        return "成功";
    }

    @RabbitListener(queues = RabbitTopicConfig.TOPIC_QUEUE_ONE)
    public void one(Channel channel, Message message) throws IOException {
        //body 即消息体
        extracted(message, "【消费者one *.two.*】 消息内容：【{}】。messageId 【{}】", channel);
    }

    @RabbitListener(queues = RabbitTopicConfig.TOPIC_QUEUE_TWO)
    public void two(Channel channel, Message message) throws IOException {
        //body 即消息体
        extracted(message, "【消费者two #】 消息内容：【{}】。messageId 【{}】", channel);
    }


    private static void extracted(Message message, String format, Channel channel) throws IOException {
        String msg = new String(message.getBody());
        String messageId = message.getMessageProperties().getMessageId();
        log.info(format, msg, messageId);
        try {
            //如果有业务逻辑，则在这里编写
            //告诉服务器收到这条消息 无需再发了 否则消息服务器以为这条消息没处理掉 后续还会在发
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            log.error("消息处理出现异常：{}", e.getMessage());
            //告诉消息服务器 消息处理异常，消息需要重新再次发送！
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
        }
    }
}
